package com.ecommerce.chat.controller;

import com.ecommerce.chat.dto.ChatRequest;
import com.ecommerce.chat.dto.ChatResponse;
import com.ecommerce.chat.service.ChatService;
import com.ecommerce.common.result.Result;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import io.swagger.annotations.ApiParam;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.servlet.mvc.method.annotation.SseEmitter;

import javax.validation.Valid;
import javax.validation.constraints.NotBlank;
import java.io.IOException;
import java.util.concurrent.CompletableFuture;

/**
 * AI客服控制器
 * 提供智能客服相关的REST接口
 */
@Slf4j
@RestController
@RequestMapping("/chat")
@Api(tags = "AI智能客服")
@Validated
public class ChatController {
    
    @Autowired
    private ChatService chatService;
    
    /**
     * 发送聊天消息（异步）
     * 
     * @param request 聊天请求
     * @return 聊天响应
     */
    @PostMapping("/send-async")
    @ApiOperation(value = "发送聊天消息（异步）", notes = "向AI客服发送消息并异步获取回复")
    public CompletableFuture<Result<ChatResponse>> sendMessageAsync(@Valid @RequestBody ChatRequest request) {
        return chatService.chatAsync(request)
                .thenApply(Result::success)
                .exceptionally(throwable -> {
                    log.error("异步聊天服务异常", throwable);
                    return Result.error("聊天服务暂时不可用，请稍后重试");
                });
    }
    
    /**
     * 发送聊天消息（同步）
     * 
     * @param request 聊天请求
     * @return 聊天响应
     */
    @PostMapping("/send")
    @ApiOperation(value = "发送聊天消息（同步）", notes = "向AI客服发送消息并获取回复")
    public Result<ChatResponse> sendMessage(@Valid @RequestBody ChatRequest request) {
        try {
            log.info("收到聊天请求 - 用户ID: {}, 会话ID: {}, 消息长度: {}", 
                    request.getUserId(), request.getSessionId(), 
                    request.getMessage() != null ? request.getMessage().length() : 0);
            
            ChatResponse response = chatService.chat(request);
            
            if (response.getSuccess()) {
                log.info("聊天响应成功 - 会话ID: {}, 回复长度: {}", 
                        response.getSessionId(), 
                        response.getReply() != null ? response.getReply().length() : 0);
                return Result.success(response);
            } else {
                log.warn("聊天响应失败 - 会话ID: {}, 错误: {}", 
                        response.getSessionId(), response.getErrorMessage());
                return Result.error(response.getErrorMessage(), response);
            }
            
        } catch (Exception e) {
            log.error("处理聊天请求异常", e);
            return Result.error("服务异常，请稍后重试");
        }
    }
    
    /**
     * 清除会话历史
     * 
     * @param sessionId 会话ID
     * @return 操作结果
     */
    @DeleteMapping("/session/{sessionId}")
    @ApiOperation(value = "清除会话历史", notes = "清除指定会话的聊天历史记录")
    public Result<Void> clearSession(
            @ApiParam(value = "会话ID", required = true)
            @PathVariable @NotBlank(message = "会话ID不能为空") String sessionId) {
        try {
            chatService.clearSession(sessionId);
            log.info("会话历史已清除 - 会话ID: {}", sessionId);
            return Result.success("会话历史已清除");
        } catch (Exception e) {
            log.error("清除会话历史失败 - 会话ID: {}", sessionId, e);
            return Result.error("清除会话历史失败");
        }
    }
    
    /**
     * 获取会话信息
     * 
     * @param sessionId 会话ID
     * @return 会话信息
     */
    @GetMapping("/session/{sessionId}/info")
    @ApiOperation(value = "获取会话信息", notes = "获取指定会话的基本信息")
    public Result<SessionInfo> getSessionInfo(
            @ApiParam(value = "会话ID", required = true)
            @PathVariable @NotBlank(message = "会话ID不能为空") String sessionId) {
        try {
            int messageCount = chatService.getSessionMessageCount(sessionId);
            SessionInfo sessionInfo = new SessionInfo(sessionId, messageCount, System.currentTimeMillis());
            return Result.success(sessionInfo);
        } catch (Exception e) {
            log.error("获取会话信息失败 - 会话ID: {}", sessionId, e);
            return Result.error("获取会话信息失败");
        }
    }
    
    /**
     * 清除响应缓存
     * 
     * @return 操作结果
     */
    @PostMapping("/clear-cache")
    @ApiOperation(value = "清除响应缓存", notes = "清除AI客服的响应缓存")
    public Result<String> clearCache() {
        try {
            chatService.clearResponseCache();
            return Result.success("缓存清除成功");
        } catch (Exception e) {
            log.error("清除缓存异常", e);
            return Result.error("缓存清除失败");
        }
    }
    
    /**
     * 流式聊天接口 - Server-Sent Events
     */
    @PostMapping("/stream")
    @ApiOperation(value = "流式AI客服聊天", notes = "使用Server-Sent Events实现流式聊天")
    public SseEmitter streamChat(@RequestBody @Valid ChatRequest request) {
        log.info("收到流式聊天请求: {}", request.getMessage());
        
        SseEmitter emitter = new SseEmitter(30000L); // 30秒超时
        
        CompletableFuture.runAsync(() -> {
            try {
                chatService.streamChat(request, emitter);
            } catch (Exception e) {
                log.error("流式聊天处理失败", e);
                try {
                    emitter.send(SseEmitter.event()
                        .name("error")
                        .data("聊天服务暂时不可用，请稍后重试"));
                    emitter.complete();
                } catch (IOException ioException) {
                    log.error("发送错误消息失败", ioException);
                    emitter.completeWithError(ioException);
                }
            }
        });
        
        return emitter;
    }
    
    /**
     * 健康检查
     * 
     * @return 健康状态
     */
    @GetMapping("/health")
    @ApiOperation(value = "健康检查", notes = "检查AI客服服务是否正常")
    public Result<String> health() {
        return Result.success("AI客服服务运行正常");
    }
    
    /**
     * 会话信息DTO
     */
    public static class SessionInfo {
        private String sessionId;
        private Integer messageCount;
        private Long timestamp;
        
        public SessionInfo(String sessionId, Integer messageCount, Long timestamp) {
            this.sessionId = sessionId;
            this.messageCount = messageCount;
            this.timestamp = timestamp;
        }
        
        // Getters
        public String getSessionId() { return sessionId; }
        public Integer getMessageCount() { return messageCount; }
        public Long getTimestamp() { return timestamp; }
        
        // Setters
        public void setSessionId(String sessionId) { this.sessionId = sessionId; }
        public void setMessageCount(Integer messageCount) { this.messageCount = messageCount; }
        public void setTimestamp(Long timestamp) { this.timestamp = timestamp; }
    }
}